package cn.iocoder.yudao.module.eval.controller.admin.subject;

import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import cn.iocoder.yudao.module.eval.controller.admin.subject.vo.*;
import cn.iocoder.yudao.module.eval.dal.dataobject.subject.EvalSubjectDO;
import cn.iocoder.yudao.module.eval.service.subject.EvalSubjectService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.Collection;
import java.util.List;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
import cn.iocoder.yudao.framework.common.pojo.PageParam;

@Tag(name = "管理后台 - 评价科目")
@RestController
@RequestMapping("/eval/subject")
@Validated
public class EvalSubjectController {

    @Resource
    private EvalSubjectService subjectService;

    @PostMapping("/create")
    @Operation(summary = "创建评价科目")
    @PreAuthorize("@ss.hasPermission('eval:subject:create')")
    public CommonResult<Long> createSubject(@Valid @RequestBody EvalSubjectSaveReqVO createReqVO) {
        return success(subjectService.createSubject(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新评价科目")
    @PreAuthorize("@ss.hasPermission('eval:subject:update')")
    public CommonResult<Boolean> updateSubject(@Valid @RequestBody EvalSubjectSaveReqVO updateReqVO) {
        subjectService.updateSubject(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除评价科目")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('eval:subject:delete')")
    public CommonResult<Boolean> deleteSubject(@RequestParam("id") Long id) {
        subjectService.deleteSubject(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得评价科目")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('eval:subject:query')")
    public CommonResult<EvalSubjectRespVO> getSubject(@RequestParam("id") Long id) {
        EvalSubjectDO subject = subjectService.getSubject(id);
        return success(BeanUtils.toBean(subject, EvalSubjectRespVO.class));
    }

    @GetMapping("/list")
    @Operation(summary = "获得评价科目列表")
    @Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048")
    @PreAuthorize("@ss.hasPermission('eval:subject:query')")
    public CommonResult<List<EvalSubjectRespVO>> getSubjectList(@RequestParam("ids") Collection<Long> ids) {
        List<EvalSubjectDO> list = subjectService.getSubjectList(ids);
        return success(BeanUtils.toBean(list, EvalSubjectRespVO.class));
    }

    @GetMapping("/page")
    @Operation(summary = "获得评价科目分页")
    @PreAuthorize("@ss.hasPermission('eval:subject:query')")
    public CommonResult<PageResult<EvalSubjectRespVO>> getSubjectPage(@Valid EvalSubjectPageReqVO pageReqVO) {
        PageResult<EvalSubjectDO> pageResult = subjectService.getSubjectPage(pageReqVO);
        return success(BeanUtils.toBean(pageResult, EvalSubjectRespVO.class));
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出评价科目 Excel")
    @PreAuthorize("@ss.hasPermission('eval:subject:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportSubjectExcel(@Valid EvalSubjectPageReqVO pageReqVO,
                                   HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<EvalSubjectDO> list = subjectService.getSubjectPage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "评价科目.xls", "数据", EvalSubjectRespVO.class,
                BeanUtils.toBean(list, EvalSubjectRespVO.class));
    }

    @GetMapping("/list-by-plan")
    @Operation(summary = "根据计划ID获得科目列表")
    @Parameter(name = "planId", description = "计划ID", required = true, example = "1")
    @PreAuthorize("@ss.hasPermission('eval:subject:query')")
    public CommonResult<List<EvalSubjectRespVO>> getSubjectListByPlanId(@RequestParam("planId") Long planId) {
        List<EvalSubjectDO> list = subjectService.getSubjectListByPlanId(planId);
        return success(BeanUtils.toBean(list, EvalSubjectRespVO.class));
    }

    @GetMapping("/list-by-type")
    @Operation(summary = "根据科目类型获得科目列表")
    @Parameter(name = "subjectType", description = "科目类型", required = true, example = "theory")
    @PreAuthorize("@ss.hasPermission('eval:subject:query')")
    public CommonResult<List<EvalSubjectRespVO>> getSubjectListBySubjectType(@RequestParam("subjectType") String subjectType) {
        List<EvalSubjectDO> list = subjectService.getSubjectListBySubjectType(subjectType);
        return success(BeanUtils.toBean(list, EvalSubjectRespVO.class));
    }

    @PostMapping("/batch-create")
    @Operation(summary = "批量创建评价科目")
    @PreAuthorize("@ss.hasPermission('eval:subject:create')")
    public CommonResult<List<Long>> batchCreateSubjects(@Valid @RequestBody EvalSubjectBatchCreateReqVO batchCreateReqVO) {
        return success(subjectService.batchCreateSubjects(batchCreateReqVO.getPlanId(), batchCreateReqVO.getSubjectList()));
    }

    @PostMapping("/copy-to-plan")
    @Operation(summary = "复制科目到其他计划")
    @PreAuthorize("@ss.hasPermission('eval:subject:create')")
    public CommonResult<List<Long>> copySubjectsToOtherPlan(@Valid @RequestBody EvalSubjectCopyReqVO copyReqVO) {
        return success(subjectService.copySubjectsToOtherPlan(copyReqVO.getSourceSubjectIds(), copyReqVO.getTargetPlanId()));
    }

    @PostMapping("/create-by-template")
    @Operation(summary = "根据模板创建科目")
    @PreAuthorize("@ss.hasPermission('eval:subject:create')")
    public CommonResult<List<Long>> createSubjectsByTemplate(@Valid @RequestBody EvalSubjectCreateByTemplateReqVO createReqVO) {
        return success(subjectService.createSubjectsByTemplate(createReqVO.getPlanId(), createReqVO.getTemplateId()));
    }

    @PutMapping("/{subjectId}/schedule")
    @Operation(summary = "设置科目考试安排")
    @Parameter(name = "subjectId", description = "科目ID", required = true)
    @PreAuthorize("@ss.hasPermission('eval:subject:schedule')")
    @ApiAccessLog(operateType = UPDATE)
    public CommonResult<Boolean> setSubjectSchedule(@PathVariable("subjectId") Long subjectId,
                                                    @Valid @RequestBody EvalSubjectScheduleReqVO scheduleReqVO) {
        subjectService.setSubjectSchedule(subjectId, scheduleReqVO);
        return success(true);
    }

    @GetMapping("/{subjectId}/schedule")
    @Operation(summary = "获取科目考试安排")
    @Parameter(name = "subjectId", description = "科目ID", required = true)
    @PreAuthorize("@ss.hasPermission('eval:subject:query')")
    public CommonResult<EvalSubjectScheduleRespVO> getSubjectSchedule(@PathVariable("subjectId") Long subjectId) {
        EvalSubjectScheduleRespVO schedule = subjectService.getSubjectSchedule(subjectId);
        return success(schedule);
    }

    @PutMapping("/{subjectId}/weight")
    @Operation(summary = "设置科目权重")
    @Parameter(name = "subjectId", description = "科目ID", required = true)
    @PreAuthorize("@ss.hasPermission('eval:subject:update')")
    @ApiAccessLog(operateType = UPDATE)
    public CommonResult<Boolean> setSubjectWeight(@PathVariable("subjectId") Long subjectId,
                                                  @RequestParam("weight") Double weight) {
        subjectService.setSubjectWeight(subjectId, weight);
        return success(true);
    }

    @PutMapping("/{subjectId}/passing-score")
    @Operation(summary = "设置科目及格分")
    @Parameter(name = "subjectId", description = "科目ID", required = true)
    @PreAuthorize("@ss.hasPermission('eval:subject:update')")
    @ApiAccessLog(operateType = UPDATE)
    public CommonResult<Boolean> setSubjectPassingScore(@PathVariable("subjectId") Long subjectId,
                                                        @RequestParam("passingScore") Integer passingScore) {
        subjectService.setSubjectPassingScore(subjectId, passingScore);
        return success(true);
    }

    @GetMapping("/{subjectId}/statistics")
    @Operation(summary = "获取科目统计信息")
    @Parameter(name = "subjectId", description = "科目ID", required = true)
    @PreAuthorize("@ss.hasPermission('eval:subject:query')")
    public CommonResult<EvalSubjectStatisticsRespVO> getSubjectStatistics(@PathVariable("subjectId") Long subjectId) {
        EvalSubjectStatisticsRespVO statistics = subjectService.getSubjectStatistics(subjectId);
        return success(statistics);
    }

    @PutMapping("/{subjectId}/status")
    @Operation(summary = "更新科目状态")
    @Parameter(name = "subjectId", description = "科目ID", required = true)
    @PreAuthorize("@ss.hasPermission('eval:subject:update')")
    @ApiAccessLog(operateType = UPDATE)
    public CommonResult<Boolean> updateSubjectStatus(@PathVariable("subjectId") Long subjectId,
                                                     @RequestParam("status") Integer status) {
        subjectService.updateSubjectStatus(subjectId, status);
        return success(true);
    }

    @GetMapping("/plan/{planId}/statistics")
    @Operation(summary = "获取计划科目统计")
    @Parameter(name = "planId", description = "计划ID", required = true)
    @PreAuthorize("@ss.hasPermission('eval:subject:query')")
    public CommonResult<EvalPlanSubjectStatisticsRespVO> getPlanSubjectStatistics(@PathVariable("planId") Long planId) {
        EvalPlanSubjectStatisticsRespVO statistics = subjectService.getPlanSubjectStatistics(planId);
        return success(statistics);
    }

    @PostMapping("/validate-config")
    @Operation(summary = "验证科目配置")
    @PreAuthorize("@ss.hasPermission('eval:subject:validate')")
    public CommonResult<EvalSubjectValidationResultRespVO> validateSubjectConfig(@Valid @RequestBody EvalSubjectValidationReqVO validationReqVO) {
        EvalSubjectValidationResultRespVO result = subjectService.validateSubjectConfig(validationReqVO);
        return success(result);
    }

}
